import { useStore } from '@/store/index.js'
import axios from '@/utils/axios/index.js'
import { showToast } from '@/utils/toast.js'

/**
 * 是否临近过期Token
 * 判断规则：预计到期时间与当前时间差值小于等于Token过期时长1/3
 */
function isTokenExpired() {
	const tokenInfo = useStore().tokenInfo
	if (!tokenInfo.token) {
		return false
	}
	const expiresIn = tokenInfo.expiresIn
	const expiresTime = new Date(tokenInfo.expiresTime).getTime()
	const currentTime = new Date().getTime()
	const diffTime = (expiresTime - currentTime) / 1000
	return diffTime <= (expiresIn / 3)
}

//定义一个空数组，用来缓存请求
let cacheRequestArr = [];
// 是否正在刷新的标志
let isRefreshing = false;

// 将所有的请求都push到数组中,其实数组是[function(token){}, function(token){},...]
function cacheRequestArrHandle(cb) {
	cacheRequestArr.push(cb);
}

// 数组中的请求得到新的token之后自执行，用新的token去重新发起请求
function afreshRequest(token) {
	cacheRequestArr.map((cb) => cb(token));
	cacheRequestArr = [];
}

export function isRefreshToken(instance, config) {
	const store = useStore();

	// 判断token是否即将过期，且不是请求刷新token的接口
	if (isTokenExpired() && config.url !== "/api/logins") {
		// 所有的请求来了，先判断是否正在刷新token，
		// 如果不是，将刷新token标志置为true并请求刷新token.
		// 如果是，则先将请求缓存到数组中
		// 等到刷新完token后再次重新请求之前缓存的请求接口即可
		if (!isRefreshing) {
			isRefreshing = true;
			const tokenInfo = store.tokenInfo
			instance.get('/api/logins', {
				query: { _action: 'refresh-token', refreshToken: tokenInfo.refreshToken },
				carryToken: false
			}).then(res => {
				const { token } = res.payload;
				store.tokenInfo = token
				uni.setStorageSync('tokenInfo', token)
				// 将刷新的token替代老的token
				config.header = {
					Authorization: 'Bearer ' + token.token
				};
				// 刷新token完成后重新发起之前的请求
				afreshRequest(token.token);
			}).catch(error => {
				showToast(error.data.message)
			}).finally(() => {
				isRefreshing = false;
			});
			// 下面这段代码一定要写，不然第一个请求的接口带过去的token还是原来的，要将第一个请求也缓存起来
			let retry = new Promise((resolve) => {
				cacheRequestArrHandle((token) => {
					// token为刷新完成后传入的token
					config.header = {
						Authorization: 'Bearer ' + token
					};
					// 将请求挂起
					resolve(config);
				});
			});
			return retry;
		} else {
			let retry = new Promise((resolve) => {
				cacheRequestArrHandle((token) => {
					// token为刷新完成后传入的token
					config.header = {
						Authorization: 'Bearer ' + token
					};
					// 将请求挂起
					resolve(config);
				});
			});
			return retry;
		}
	} else {
		return config;
	}
}